﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SerialChart
{
    public class SerialDataFactory : FrameFactory
    {
        //protected Queue<R_Frame> recFrameQueue = new Queue<R_Frame>();//接收帧队列
        //protected Queue<Frame_aNCI> aNciQueue = new Queue<Frame_aNCI>();//发送指令队列
        public List<int> DataList = new List<int>();
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="_stream">接入的数据流</param>
        public SerialDataFactory(IFrameStream _stream)
            : base(_stream)
        {
        }

        public void Send(byte[] data)
        {
            stream.Send(data);
        }


        protected override void FrameSendThread()
        {

            //stream.Send();
            OnFrameSended(EventArgs.Empty);
        }

        public string Hex2String(Byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("X2") + " ");
            }
            return sb.ToString();
        }


        //新协议
        //帧头A5 5A addr cmd ext data3 data2 data1 data0 sum 10各字节

        private byte[] recData = new byte[10];
        private int recPtr = 0;
        enum RecState { IDLE, HEADREADY, RECING, };
        RecState recState = RecState.IDLE;

        /// <summary>
        /// 串口数据解析线程
        /// 接收机器人返回数据，从协议帧中解析出机器人数据
        /// </summary>
        protected override void FrameRecThread()
        {
            while (keepRec)
            {
                if (stream.available > 0)
                {
                    byte data = stream.Read();
                    switch (recState)
                    {
                        case RecState.IDLE:
                            if (data == 0xA5)
                            {
                                recPtr = 0;
                                recData[recPtr++] = 0xA5;
                                recState = RecState.HEADREADY;
                            }
                            break;
                        case RecState.HEADREADY:
                            if (data == 0x5A)
                            {
                                recData[recPtr++] = 0x5A;
                                recState = RecState.RECING;
                            }
                            else
                            {
                                recPtr = 0;
                                recState = RecState.IDLE;
                            }
                            break;
                        case RecState.RECING:
                            if (recPtr < 10)
                                recData[recPtr++] = data;
                            else
                            {
                                //OnFrameReceived(new FrameRecEventArgs(recData));
                                process(recData);
                                recPtr = 0;
                                recState = RecState.IDLE;
                            }
                            break;
                    }
                }
                else
                {
                    Thread.Sleep(20);
                }

            }
        }

        private void process(Byte[] recData)
        {
            if (recData[2] == 0x00)//验证地址
            {
                switch (recData[3])//执行指令
                { 
                    case 0x00:
                        if (recData[4] == 0x00)//int型数据
                        {
                            List_AddData(BitConverter.ToInt32(recData, 5));
                        }
                        break;
                    case 0x01:
                        break;
                    case 0x02:
                        break;
                    case 0x03:
                        break;
                }
            }
        
        }

        public void List_AddData(int Data)
        {
            // this.chart1.Series[0].Points.Add(Data);
            DataList.Add(Data);
            if (DataList.Count > 100)
                DataList.RemoveAt(0);
        }
    }

    public class FrameRecEventArgs : EventArgs
    {
        public Byte[] Data;

        public FrameRecEventArgs(Byte[] data)
        {
            Data = data;
        }
    }

}
